package xyz.cerberu.cet.shiro.realm;

import xyz.cerberu.cet.user.dao.RoleDao;
import xyz.cerberu.cet.user.dao.UserDao;
import xyz.cerberu.cet.user.domain.User;
import xyz.cerberu.cet.user.exception.UserBanAccountException;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @author β世界
 * @Name β世界
 * Created on 23:02
 * @Description 用户登陆Realm
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;

    /**
     * @author β世界 on 23:03 2020/6/18
     * 用户权限验证器
     * @param principals: 负责器
     * @return org.apache.shiro.authz.AuthorizationInfo
     **/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();

        // 角色集合
        Set<String> roles = new HashSet<>();

        // 查询这个用户所拥有的的权限
        roles.add(roleDao.findByID(user.getRole().getRid()).getRole());

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
        return authorizationInfo;
    }

    /**
     * @author β世界 on 23:04 2020/6/18
     * 用户登陆的凭证校验器
     * @param token: 用户的信息封装对象
     * @return org.apache.shiro.authc.AuthenticationInfo
     **/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken uToken = (UsernamePasswordToken) token;

        // 查询这个用户是否存在
        User user = userDao.findByEmail(uToken.getUsername());

        if(user == null){
            // 当用户不存在的时候，就抛出UnknownAccountException异常
            throw new UnknownAccountException("用户不存在");
            // 检查用户是否被ban
        }else if(user.getRole().getRid() == -1){
            throw new UserBanAccountException("账户被封禁");
        }

        // 获取盐来进行管理
        ByteSource salt = ByteSource.Util.bytes(user.getEmail());

        return new SimpleAuthenticationInfo(user,user.getPassword(),salt,getName());
    }
}
